#ifndef __ASIO_IO_CONTEXT_POOL_H__
#define __ASIO_IO_CONTEXT_POOL_H__

#include <cstddef>
#include <vector>
#include <memory>
#include <thread>

#include <boost/beast/http.hpp>
#include <boost/beast.hpp>
#include <boost/asio.hpp>

//封装 Asio Context 连接池
//每一个 io_context 都有一个独立的线程
//每一个 io_context 都有一个 work 对象，保证不会自动退出
//每次获取 io_context 都是轮询的方式返回
class AsioIoContextPool
{
public:
    using IOContext = boost::asio::io_context;
    using Work = boost::asio::io_context::work;
    using WorkPtr = std::shared_ptr<Work>;

    AsioIoContextPool(const AsioIoContextPool&) = delete;
    AsioIoContextPool& operator=(const AsioIoContextPool&) = delete;

    AsioIoContextPool(std::size_t size = std::thread::hardware_concurrency());
    ~AsioIoContextPool(){ Stop(); };

    //返回一个 io_context 上下文
    IOContext& GetIoContext();

    //关闭线程池
    void Stop();

private:
    std::vector<IOContext> _io_contexts;
    std::vector<WorkPtr> _works; //保证每个 io_context 都不会自动退出
    std::vector<std::thread> _threads;
    std::atomic<std::size_t> _next{0};
};


#endif // !__ASIO_IO_CONTEXT_POOL_H__